<?php
namespace util\plugin;
use soa\client;

class verifyCode extends client{
    private $_im;
    private $_distortion_im;

    //验证码图片大小
    private $_im_x;
    private $_im_y;

    private $_font_size = 20;

    private $_number_only = false;

    private $_key_length = 4;

    private $_background_color;
    private $_txt_color;

    private $_font_path;

    private $_save_time;

    public $case_sensitive = false;

    public function __construct($fontNum = '' , $fontSize = '', $saveTime = 300 , $x = 120, $y = 35){
        $this->_im_x = $x;
        $this->_im_y = $y;
        if($fontNum) $this->_key_length = $fontNum;
        if($fontSize)$this->_font_size = $fontSize;
        $this->_save_time = $saveTime;
        $this->_font_path = __DIR__.'/airbus.ttf';
    }

    //设置图片的大小
    public function setSize($width = 160,$height = 40){
        $this->_im_x = $width;
        $this->_im_y = $height;
    }

    //纯数字验证码
    public function setNumberOnly($numberOnly){
        $this->_number_only = $numberOnly;
    }

    //设置字体
    public function setFont($font_path){
        $this->_font_path = $font_path;
    }

    public function setKeyLength($key_length){
        $this->_key_length = $key_length;
    }

    /**
     * 获取验证码
     */
    public function code($key){
        if(empty($key))
            exit;

        $randomStr = $this->_randomKey($this->_key_length);

        $this->_buildImage($randomStr ,$this->_font_size);

        if(!$this->case_sensitive)
            $randomStr = strtolower($randomStr);

        $randomStr .= md5($key);

        \artisan\secure\captcha::create($randomStr,$this->_save_time);

        $this->_output();
    }

    /**
     * 验证验证码
     * @param $code
     * @param $timeStamp
     * @return bool
     */
    public function verify($key,$code){
        if(empty($key) || empty($code))
            return false;

        if(!$this->case_sensitive)
            $code = strtolower($code);

        $code .= md5($key);

        $result = \artisan\secure\captcha::verify($code);

        if($result){
            return true;
        }else{
            return false;
        }
    }

    //生成图片
    private function _buildImage($text,$fontSize,$pixelCount = 160) {

        $this->_im = imagecreatetruecolor($this->_im_x,$this->_im_y);
        $this->_txt_color = $this->_randomColor($this->_im);
        $this->_background_color = $this->_randomColor($this->_im , 250,235,215);
        imagefill($this->_im, 16, 13, $this->_background_color);

        $tlen = strlen($text);
        for ($i=0; $i < $tlen; $i++) {
            $tmp =substr($text,$i,1);
            $array = array(-1,1);
            $p = array_rand($array);
            $an = $array[$p]*mt_rand(1,10);

            if($this->_font_path){
                imagettftext($this->_im, $fontSize, $an, 15+ $i * $fontSize, $this->_im_y * 80 / 100 , $this->_txt_color, $this->_font_path, $tmp);
            }else{
                imagestring($this->_im, $fontSize , 15 + $i * $fontSize , $this->_im_y / 2,$tmp, $this->_txt_color);
            }
        }

        $this->_setDistortion();
        $this->_setPixel($pixelCount);
    }

    //随机获取颜色
    private function _randomColor($im ,$min_r = 0 , $min_g = 0 , $min_b = 0){
        return ImageColorAllocate($im, mt_rand($min_r,255),mt_rand($min_g,255),mt_rand($min_b,255));
    }

    //验证码变形
    private function _setDistortion(){

        $this->_distortion_im = imagecreatetruecolor ($this->_im_x,$this->_im_y);

        imagefill($this->_distortion_im, 16, 13, $this->_background_color);
        for ( $i=0; $i< $this->_im_x; $i++) {
            for ( $j=0; $j< $this->_im_y; $j++) {
                $rgb = imagecolorat($this->_im, $i , $j);
                if( (int)($i+20+sin($j/$this->_im_y*2*M_PI)*10) <= imagesx($this->_distortion_im)&& (int)($i+20+sin($j/$this->_im_y*2*M_PI)*10) >=0 ) {
                    imagesetpixel ($this->_distortion_im, (int)($i+10+sin($j/$this->_im_y*2*M_PI-M_PI*0.1)*4) , $j , $rgb);
                }
            }
        }
    }

    //干扰
    private function _setPixel($count){
        if(!$count){
            return;
        }

        for($i=0; $i<$count; $i++){
            $randcolor = $this->_randomColor($this->_distortion_im);
            imagesetpixel($this->_distortion_im, mt_rand() % $this->_im_x , mt_rand() % $this->_im_y , $randcolor);
        }

        $rand = mt_rand(5,30);
        $rand1 = mt_rand(15,25);
        $rand2 = mt_rand(5,10);
        for ($yy=$rand; $yy<=+$rand+2; $yy++){
            for ($px=-80;$px<=80;$px=$px+0.1) {
                $x=$px/$rand1;
                if ($x!=0) {
                    $y=sin($x);
                }
                $py=$y*$rand2;
                imagesetpixel($this->_distortion_im, $px+80, $py+$yy, $this->_txt_color);
            }
        }
    }

    private function _output(){
        header("Content-type: image/JPEG");
        ImagePNG($this->_distortion_im);
        ImageDestroy($this->_distortion_im);
        ImageDestroy($this->_im);
    }

    //验证码内容
    private function _randomKey($size){
        if( $this->_number_only){
            $alphabet = '0123456789';
        }else{
            $alphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
        }

        $l = strlen($alphabet)-1;
        $key = '';
        for ($i=0; $i<$size; $i++){
            $key.= $alphabet[mt_rand(0, $l)];
        }
        return $key;
    }
}